// META: title=test WebNN API element-wise mul operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long

'use strict';

// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-binary
// Compute the element-wise binary multiplication of the two input tensors.
// MLOperand mul(MLOperand a, MLOperand b);


const getMulPrecisionTolerance = (graphResources) => {
  const toleranceValueDict = {float32: 1, float16: 1};
  const expectedDataType =
      getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
  return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
};

const mulTests = [
  {
    'name': 'mul float32 1D constant tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'},
          'constant': true
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 1D tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 2D tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 3D tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 4D tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 5D tensors',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 1, 2, 3], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            74.96137237548828,   -34.53953170776367,  -33.316162109375,
            53.92023849487305,   -83.69075012207031,  19.785221099853516,
            36.28113555908203,   -34.31147766113281,  49.10429000854492,
            -54.538848876953125, 70.77384948730469,   -55.18768310546875,
            -93.96234130859375,  60.08298110961914,   -92.7341537475586,
            87.6099853515625,    -8.881865501403809,  71.79511260986328,
            -26.158620834350586, -18.935443878173828, 34.6467170715332,
            -60.95826721191406,  -11.119653701782227, 77.50324249267578
          ],
          'descriptor': {'dimensions': [2, 2, 1, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3681.4443359375,    -411.278076171875,   703.4972534179688,
            3814.802978515625,  7910.138671875,      -1855.63720703125,
            405.582763671875,   1125.6197509765625,  4091.3193359375,
            -4969.61962890625,  -7.951977252960205,  -849.7775268554688,
            1264.6595458984375, -3041.78955078125,   2891.103759765625,
            -579.6376342773438, -192.98143005371094, 1581.7545166015625,
            2197.89208984375,   1781.2109375,        2037.47900390625,
            3844.01513671875,   -36.79807662963867,  766.0423583984375
          ],
          'descriptor': {'dimensions': [2, 2, 1, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 broadcast 1D to 4D',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [67.50372314453125],
          'descriptor': {'dimensions': [1], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3315.18994140625,   803.7978515625,      -1425.394775390625,
            4775.82080078125,   -6380.20068359375,   -6331.1103515625,
            754.6165771484375,  -2214.52197265625,   5624.34130859375,
            6150.98828125,      -7.5845537185668945, 1039.4193115234375,
            -908.5472412109375, -3417.4755859375,    -2104.513427734375,
            -446.6123352050781, 1466.6925048828125,  1487.208740234375,
            -5671.7783203125,   -6349.91064453125,   3969.7099609375,
            -4256.77001953125,  223.388916015625,    667.20703125
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 broadcast 2D to 4D',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            -97.29339599609375, -81.70872497558594, -63.859336853027344,
            -25.192203521728516, 94.61557006835938, -20.381790161132812
          ],
          'descriptor': {'dimensions': [2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            -4778.197265625,     -972.9432983398438,
            1348.440673828125,   -1782.3232421875,
            -8942.7119140625,    1911.5888671875,
            -1087.6319580078125, 2680.5302734375,
            -5320.69482421875,   -2295.531982421875,
            -10.630775451660156, -313.8379211425781,
            1309.492919921875,   4136.625,
            1990.89501953125,    166.67449951171875,
            2055.767333984375,   -449.04156494140625,
            8174.7578125,        7686.14013671875,
            -3755.3935546875,    1588.6148681640625,
            313.10968017578125,  -201.4536895751953
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 broadcast 3D to 4D',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            8.696772575378418, 48.377689361572266, 97.7515869140625,
            62.21574783325195
          ],
          'descriptor': {'dimensions': [2, 2, 1], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            427.1091003417969,   103.55646514892578, -183.63926696777344,
            3422.673095703125,   -4572.4794921875,   -4537.2978515625,
            1092.7540283203125,  -3206.8310546875,   8144.5625,
            5669.14404296875,    -6.990409851074219, 957.995361328125,
            -117.05175018310547, -440.2869567871094, -271.1328125,
            -320.07232666015625, 1051.130126953125,  1065.8333740234375,
            -8213.255859375,     -9195.2529296875,   5748.50439453125,
            -3923.3115234375,    205.88949584960938, 614.940673828125
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'mul float32 broadcast 4D to 4D',
    'graph': {
      'inputs': {
        'inputA': {
          'data': [67.50372314453125],
          'descriptor': {'dimensions': [1, 1, 1, 1], 'dataType': 'float32'}
        },
        'inputB': {
          'data': [
            49.1112174987793,    11.907459259033203,   -21.115795135498047,
            70.7490005493164,    -94.51628112792969,   -93.78905487060547,
            11.178888320922852,  -32.80592346191406,   83.31897735595703,
            91.1207275390625,    -0.11235756427049637, 15.397955894470215,
            -13.459217071533203, -50.6264762878418,    -31.17625617980957,
            -6.616114139556885,  21.72757911682129,    22.03150749206543,
            -84.02171325683594,  -94.06755828857422,   58.807273864746094,
            -63.059783935546875, 3.3092827796936035,   9.884003639221191
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'mul',
        'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
        'outputs': 'output'
      }],
      'expectedOutputs': {
        'output': {
          'data': [
            3315.18994140625,   803.7978515625,      -1425.394775390625,
            4775.82080078125,   -6380.20068359375,   -6331.1103515625,
            754.6165771484375,  -2214.52197265625,   5624.34130859375,
            6150.98828125,      -7.5845537185668945, 1039.4193115234375,
            -908.5472412109375, -3417.4755859375,    -2104.513427734375,
            -446.6123352050781, 1466.6925048828125,  1487.208740234375,
            -5671.7783203125,   -6349.91064453125,   3969.7099609375,
            -4256.77001953125,  223.388916015625,    667.20703125
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  }
];

if (navigator.ml) {
  mulTests.forEach((test) => {
    webnn_conformance_test(
        buildGraphAndCompute, getMulPrecisionTolerance, test);
  });
} else {
  test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}
